package cn.yunyichina.provider.register.service.impl;

import cn.yunyichina.provider.framework.dubbo.service.BaseService;
import cn.yunyichina.provider.framework.dubbo.service.HisifaceService;
import cn.yunyichina.provider.framework.dubbo.service.PayService;
import cn.yunyichina.provider.iface.entity.base.OrderExtVo;
import cn.yunyichina.provider.iface.entity.common.ResCommon;
import cn.yunyichina.provider.iface.entity.common.Response;
import cn.yunyichina.provider.iface.entity.hisiface.register.*;
import cn.yunyichina.provider.iface.entity.pay.PaymentJournalVo;
import cn.yunyichina.utils.commons.DateUtils;
import cn.yunyichina.utils.convert.JsonUtils;
import cn.yunyichina.utils.convert.ObjectParser;
import cn.yunyichina.utils.log.Log;
import cn.yunyichina.utils.log.constant.LogParamType;
import cn.yunyichina.utils.log.constant.LogScene;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 挂号医保
 * Created by Administrator on 2017/6/6.
 */
@Service
public class RegInsuranceServiceImpl {
    private Logger logger = LoggerFactory.getLogger(RegInsuranceServiceImpl.class);

    @Autowired
    PayServiceImpl payService;

    /**
     * 挂号医保结算 yyt.register.reg.insurance.settle
     * @param data
     * @param sessionId
     * @return
     */
    public Response settleRegInsurance(String data, String sessionId) {
        logger.info("settleRegInsurance, request data=" + data + ", sessionId=" + sessionId);
        Response response = new Response();

        Map<String,Object> requestVo = JsonUtils.parseObject(data, Map.class);
        String orderNo = (String) requestVo.get("order_no");
        if(StringUtils.isBlank(orderNo)){
            response.setResultCodeAndMessage("-1","订单号不能为空");
        }

        Map<String, Object> dataMap = new HashMap<String, Object>();
        dataMap.put("order_no", orderNo);
        dataMap.put("order_type", OrderExtVo.ORDER_TYPE_REGISTER);
        Response ordResponse = BaseService.callUnderlineFromInternal(sessionId, "yyt.base.order.by.orderno.get",
                JsonUtils.toJsonString(dataMap));
//        logger.info("settleRegInsurance, yyt.base.order.by.orderno.get ordResponse=" + JSON.toJSONString(ordResponse));
        if (!"0".equals(ordResponse.getResultCode())) {
            response.setResultCodeAndMessage(ordResponse.getResultCode(), ordResponse.getResultMessage());
            return response;
        }
        OrderExtVo order = JsonUtils.parseObject(ordResponse.getResult(), OrderExtVo.class);
        if(order == null){
            response.setResultCodeAndMessage("6002", "订单不存在。");
            return response;
        }

        Map<String, String> extraParamsMap = JsonUtils.parseObject(order.getExtraParams(),Map.class);
        String ssInfoStr = extraParamsMap.get("s_s_info");
        Map<String,String> ssInfoMap = JsonUtils.parseObject(ssInfoStr,Map.class);

        SettleRegisterInsuranceVo hisVo = new SettleRegisterInsuranceVo();
        hisVo.setHospitalCode(order.getOrgCode());
        hisVo.setBranchCode(order.getBranchCode());
        hisVo.setSsFeeNo(ssInfoMap.get("mzlsh"));
        hisVo.setSsBillNo("");//医保结算业务单据号
        hisVo.setInsuranceCardEncrypt(extraParamsMap.get("insurance_card_encrypt"));//医保卡所得加密串
//        hisVo.setInsuranceCardPwd(extraParamsMap.get("insurance_card_pwd"));//医保卡密码
        hisVo.setInsuranceCardPwd("0");//医保卡密码,默认为0
        hisVo.setInsurancePatType(ssInfoMap.get("brlx"));
        hisVo.setDeptCode(ssInfoMap.get("ksbm"));
        hisVo.setDeptName(ssInfoMap.get("ksmc"));
        hisVo.setRegFee(ssInfoMap.get("ghf"));
        hisVo.setTreatFee(ssInfoMap.get("zjzj"));
        hisVo.setExpertFee(StringUtils.isBlank(ssInfoMap.get("zjf"))?"0":ssInfoMap.get("zjf"));
        hisVo.setPayAmount(ssInfoMap.get("ssj"));
        hisVo.setRansomAmount(ssInfoMap.get("zsj"));

        ResCommon<SettleRegisterInsuranceVoResponse> hisResponse = HisifaceService.getHisifaceClient().settleRegisterInsurance(hisVo);
//        logger.info("settleRegInsurance,call hisiface request={},response={}",JsonUtils.toJsonString(hisVo),JsonUtils.toJsonString(hisResponse));
        Log.i(LogScene.REGISTER_INSURANCE,"yyt.register.reg.insurance.settle", LogParamType.REQUEST,order.getOrderNo(),
                "call hisiface settleRegisterInsurance request=" + JSONObject.toJSONString(hisVo));
        Log.i(LogScene.REGISTER_INSURANCE,"yyt.register.reg.insurance.settle", LogParamType.RESPONSE,order.getOrderNo(),
                "call hisiface settleRegisterInsurance response=" + JSONObject.toJSONString(hisResponse));
        if("0".equals(hisResponse.getResultCode())){
            SettleRegisterInsuranceVoResponse settleResponse = JsonUtils.parseObject(hisResponse.getResult(), SettleRegisterInsuranceVoResponse.class);
            List<Info> ssItems = settleResponse.getSsItems();
            extraParamsMap.put("ss_items",JsonUtils.toJsonString(ssItems));//社保支付结果串,写单时需要传给his
            order.setPayAmount(ObjectParser.toInteger(settleResponse.getPayAmount()));
            order.setInsuranceAmount(ObjectParser.toInteger(settleResponse.getInsuranceAmount()));
            order.setInsuranceSettleFlag((short) 1);//医保结算标记 1 成功
            order.setExtraParams(JsonUtils.toJsonString(extraParamsMap));
            order.setInsuranceMode((short) 4);
            if("0".equals(settleResponse.getPayAmount())){
                //全额医保，更改支付状态,写单
                order.setPayStatus(OrderExtVo.ORDER_PAY_STATUS_PAYED);
                //更新订单后再写单
                BaseService.callUnderlineFromInternal(sessionId,"yyt.base.order.update", JsonUtils.toJsonString(order));
                try {
                    String payData = "{\"yyt_order_no\":\"" + order.getOrderNo() +"\"}";
                    payService.ackPayRegRecord(payData,sessionId);
                    //全额医保,添加流水
                    addPaymentJournal(order);
                }catch (Exception e){
                    e.printStackTrace();
                    logger.error("settleRegInsurance,调用写单出现异常，订单号" + order.getOrderNo() );
                }
            }else{
                BaseService.callUnderlineFromInternal(sessionId,"yyt.base.order.update", JsonUtils.toJsonString(order));
            }
        }else{
            order.setInsuranceSettleFlag((short) 2);//医保结算标记 2 失败
            order.setInsuranceMode((short) 4);
            //更新订单
            BaseService.callUnderlineFromInternal(sessionId,"yyt.base.order.update", JsonUtils.toJsonString(order));
        }


        response.setResultCodeAndMessage(hisResponse.getResultCode(),hisResponse.getResultMessage());
        response.setResult(JsonUtils.toJsonString(hisResponse.getResult()));
        return response;
    }


    /**
     * 挂号医保退款 yyt.register.reg.insurance.refund
     * @param data
     * @param sessionId
     * @return
     */
    public Response refundRegInsurance(String data, String sessionId) {
        logger.info("refundRegInsurance, 挂号医保结算退款 request data=" + data + ", sessionId=" + sessionId);
        Response response = new Response();

        Map<String,Object> requestVo = JsonUtils.parseObject(data, Map.class);
        String orderNo = (String) requestVo.get("order_no");
        if(StringUtils.isBlank(orderNo)){
            response.setResultCodeAndMessage("-1","订单号不能为空");
        }

        Map<String, Object> dataMap = new HashMap<String, Object>();
        dataMap.put("order_no", orderNo);
        dataMap.put("order_type", OrderExtVo.ORDER_TYPE_REGISTER);
        Response ordResponse = BaseService.callUnderlineFromInternal(sessionId, "yyt.base.order.by.orderno.get",
                JsonUtils.toJsonString(dataMap));
//        logger.info("refundRegInsurance, yyt.base.order.by.orderno.get ordResponse=" + JSON.toJSONString(ordResponse));
        if (!"0".equals(ordResponse.getResultCode())) {
            logger.error("refundRegInsurance,查询不到订单：" + orderNo);
            response.setResultCodeAndMessage(ordResponse.getResultCode(), ordResponse.getResultMessage());
            return response;
        }
        OrderExtVo order = JsonUtils.parseObject(ordResponse.getResult(), OrderExtVo.class);
        if(order == null){
            response.setResultCodeAndMessage("6002", "订单不存在。");
            return response;
        }
        Map<String, String> extraParamsMap = JsonUtils.parseObject(order.getExtraParams(),Map.class);
        String ssInfoStr = extraParamsMap.get("s_s_info");
        Map<String,String> ssInfoMap = JsonUtils.parseObject(ssInfoStr,Map.class);


        RefundRegisterInsuranceVo hisVo = new RefundRegisterInsuranceVo();
        hisVo.setHospitalCode(order.getOrgCode());
        hisVo.setBranchCode(order.getBranchCode());
        hisVo.setSsFeeNo(ssInfoMap.get("cancel_serial_no"));
        hisVo.setSsBillNo("");//医保结算业务单据号
        hisVo.setInsuranceCardEncrypt(extraParamsMap.get("insurance_card_encrypt"));//医保卡所得加密串
        hisVo.setInsuranceCardPwd("0");//医保卡密码默认为0，extraParamsMap.get("insurance_card_pwd")
        hisVo.setInsurancePatType(ssInfoMap.get("brlx"));
        hisVo.setDeptCode(ssInfoMap.get("ksdm"));
        hisVo.setDeptName(ssInfoMap.get("ksmc"));
        hisVo.setRegFee(ssInfoMap.get("ghf"));
        hisVo.setTreatFee(ssInfoMap.get("zjzj"));
        hisVo.setExpertFee(StringUtils.isBlank(ssInfoMap.get("zjf"))?"0":ssInfoMap.get("zjf"));
        hisVo.setPayAmount(ssInfoMap.get("ssj"));
        hisVo.setRansomAmount(ssInfoMap.get("zsj"));

        ResCommon hisResponse = HisifaceService.getHisifaceClient().refundRegisterInsurance(hisVo);
//        logger.info("refundRegInsurance,call hisiface refundRegisterInsurance request={},response={}",JsonUtils.toJsonString(hisVo),JsonUtils.toJsonString(hisResponse));
        Log.i(LogScene.REGISTER_INSURANCE,"yyt.register.reg.insurance.refund", LogParamType.REQUEST,order.getOrderNo(),
                "call hisiface refundRegisterInsurance request=" + JSONObject.toJSONString(hisVo));
        Log.i(LogScene.REGISTER_INSURANCE,"yyt.register.reg.insurance.refund", LogParamType.RESPONSE,order.getOrderNo(),
                "call hisiface refundRegisterInsurance response=" + JSONObject.toJSONString(hisResponse));

        response.setResultCodeAndMessage(hisResponse.getResultCode(),hisResponse.getResultMessage());
        response.setResult(JsonUtils.toJsonString(hisResponse.getResult()));
        return response;
    }


    /**21003
     * 增加医保结算流水
     * @param order
     */
    private void addPaymentJournal(OrderExtVo order) {
        PaymentJournalVo tmp = new PaymentJournalVo();
        tmp.setOrderNo(order.getOrderNo());
        tmp.setPayStatus((short) 1);//交易状态
        Response findPaymentJournalResponse = PayService.callUnderlineFromInternal("yyt.pay.payment.journal.find",
                JsonUtils.toJsonString(tmp));
        logger.info("addRefundPaymentJournal, findPaymentJournalResponse=" + JSON.toJSONString(findPaymentJournalResponse));
        if ("0".equals(findPaymentJournalResponse.getResultCode())) {
            List<PaymentJournalVo> list = JsonUtils.parseArray(findPaymentJournalResponse.getResult(), PaymentJournalVo.class);
            int totalAmount = 0;
            for (PaymentJournalVo paymentJournalVo : list) {
                totalAmount += paymentJournalVo.getTotalAmount().intValue();
            }
            if(order.getTotalAmount().intValue() <= totalAmount) {
                logger.info("addPaymentJournal, 退费流水已存在，不再添加。");
                return;
            }
        }

        PaymentJournalVo paymentJournal=new PaymentJournalVo();
        paymentJournal.setOrgId(order.getOrgId());
        paymentJournal.setOrgName(order.getOrgName());
        paymentJournal.setOrgCode(order.getOrgCode());
        paymentJournal.setBranchId(order.getBranchId());
        paymentJournal.setBranchName(order.getBranchName());
        paymentJournal.setOrderNo(order.getOrderNo());
        paymentJournal.setOutOrderNo(order.getOutOrderNo());
        paymentJournal.setPaymentDealId(order.getPaymentDealId());

        paymentJournal.setMedicareAmount(order.getMedicareAmount());
        paymentJournal.setAccountAmount(order.getAccountAmount());
        paymentJournal.setInsuranceAmount(order.getInsuranceAmount());
        paymentJournal.setTotalAmount(order.getInsuranceAmount());
        paymentJournal.setPayAmount(0);


        paymentJournal.setPlatformId(order.getPlatformId());
        paymentJournal.setPlatformCode(order.getPlatformCode());
        paymentJournal.setPlatformName(order.getPlatformName());
        paymentJournal.setPlatformOrgAppName(order.getPlatformOrgAppName());
        paymentJournal.setPlatformOrgAppCode(order.getPlatformOrgAppCode());
        paymentJournal.setPayAppId(order.getPayAppId());
        paymentJournal.setDealAccount("");
        paymentJournal.setAccountName("");
        paymentJournal.setPayStatus((short) 1);
        paymentJournal.setHisOrderNo(order.getHisOrderNo());
        paymentJournal.setOrderType(order.getOrderType());
        paymentJournal.setCheckStatus((short)0);
        paymentJournal.setPayTime(DateUtils.dateToString(new Date()));
        paymentJournal.setPayMode((short) order.getPayMode().intValue());

        paymentJournal.setPlatformOrgAppCode(order.getPlatformOrgAppCode());
        paymentJournal.setBranchId(order.getBranchId());
        paymentJournal.setBranchName(order.getBranchName());
        paymentJournal.setSettlementStatus((short) 0);
        if (order.getInsuranceMode() != null) {
            paymentJournal.setInsuranceMode((short) order.getInsuranceMode().intValue());
        }
        paymentJournal.setBranchId(order.getBranchId());
        paymentJournal.setBranchName(order.getBranchName());
        paymentJournal.setBranchCode(order.getBranchCode());

        logger.info("新增医保结算流水请求参数->" + JSON.toJSONString(paymentJournal));
        Response addPaymentJournalResponse = PayService.callUnderlineFromInternal("yyt.pay.payment.journal.add",
                JsonUtils.toJsonString(paymentJournal));
        logger.info("新增医保结算流水返回参数->" + JSON.toJSONString(addPaymentJournalResponse));
    }
}
